home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / c / icu-1.3.1 / icu-bin / include / ubidi.h < prev    next >
C/C++ Source or Header  |  2000-02-23  |  36KB  |  889 lines

  1. /*
  2. *******************************************************************************
  3. *                                                                             *
  4. * COPYRIGHT:                                                                  *
  5. *   (C) Copyright International Business Machines Corporation, 1999           *
  6. *   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
  7. *   US Government Users Restricted Rights - Use, duplication, or disclosure   *
  8. *   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
  9. *                                                                             *
  10. *******************************************************************************
  11. *   file name:  ubidi.h
  12. *   encoding:   US-ASCII
  13. *   tab size:   8 (not used)
  14. *   indentation:4
  15. *
  16. *   created on: 1999jul27
  17. *   created by: Markus W. Scherer
  18. */
  19.  
  20. #ifndef UBIDI_H
  21. #define UBIDI_H
  22.  
  23. #include "utypes.h"
  24. #include "uchar.h"
  25.  
  26. /*
  27.  * javadoc-style comments are intended to be transformed into HTML
  28.  * using DOC++ - see
  29.  * http://www.zib.de/Visual/software/doc++/index.html .
  30.  *
  31.  * The HTML documentation is created with
  32.  *  doc++ -H ubidi.h
  33.  *
  34.  * The following #define trick allows us to do it all in one file
  35.  * and still be able to compile it.
  36.  */
  37. #define DOCXX_TAG
  38. #define BIDI_SAMPLE_CODE
  39.  
  40. /**
  41.  * @name BiDi algorithm for ICU
  42.  *
  43.  * <h2>BiDi algorithm for ICU</h2>
  44.  *
  45.  * This is an implementation of the Unicode Bidirectional algorithm.
  46.  * The algorithm is defined in the
  47.  * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
  48.  * version 5, also described in The Unicode Standard, Version 3.0 .<p>
  49.  *
  50.  * <h3>General remarks about the API:</h3>
  51.  *
  52.  * In functions with an error code parameter,
  53.  * the <code>pErrorCode</code> pointer must be valid
  54.  * and the value that it points to must not indicate a failure before
  55.  * the function call. Otherwise, the function returns immediately.
  56.  * After the function call, the value indicates success or failure.<p>
  57.  *
  58.  * The <quote>limit</quote> of a sequence of characters is the position just after their
  59.  * last character, i.e., one more than that position.<p>
  60.  *
  61.  * Some of the API functions provide access to <quote>runs</quote>.
  62.  * Such a <quote>run</quote> is defined as a sequence of characters
  63.  * that are at the same embedding level
  64.  * after performing the BiDi algorithm.<p>
  65.  *
  66.  * @author Markus W. Scherer
  67.  * @version 1.0
  68.  */
  69. DOCXX_TAG
  70. /*@{*/
  71.  
  72. /**
  73.  * UBiDiLevel is the type of the level values in this
  74.  * BiDi implementation.
  75.  * It holds an embedding level and indicates the visual direction
  76.  * by its bit 0 (even/odd value).<p>
  77.  *
  78.  * It can also hold non-level values for the
  79.  * <code>paraLevel</code> and <code>embeddingLevels</code>
  80.  * arguments of <code>ubidi_setPara()</code>; there:
  81.  * <ul>
  82.  * <li>bit 7 of an <code>embeddingLevels[]</code>
  83.  * value indicates whether the using application is
  84.  * specifying the level of a character to <i>override</i> whatever the
  85.  * BiDi implementation would resolve it to.</li>
  86.  * <li><code>paraLevel</code> can be set to the
  87.  * pesudo-level values <code>UBIDI_DEFAULT_LTR</code>
  88.  * and <code>UBIDI_DEFAULT_RTL</code>.</li>
  89.  *
  90.  * @see ubidi_setPara
  91.  *
  92.  * <p>The related constants are not real, valid level values.
  93.  * <code>UBIDI_DEFAULT_XXX</code> can be used to specify
  94.  * a default for the paragraph level for
  95.  * when the <code>ubidi_setPara()</code> function
  96.  * shall determine it but there is no
  97.  * strongly typed character in the input.<p>
  98.  *
  99.  * Note that the value for <code>UBIDI_DEFAULT_LTR</code> is even
  100.  * and the one for <code>UBIDI_DEFAULT_RTL</code> is odd,
  101.  * just like with normal LTR and RTL level values -
  102.  * these special values are designed that way. Also, the implementation
  103.  * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
  104.  *
  105.  * @see UBIDI_DEFAULT_LTR
  106.  * @see UBIDI_DEFAULT_RTL
  107.  * @see UBIDI_LEVEL_OVERRIDE
  108.  * @see UBIDI_MAX_EXPLICIT_LEVEL
  109.  */
  110. typedef uint8_t UBiDiLevel;
  111.  
  112. /** @memo If there is no strong character, then set the paragraph level to 0 (left-to-right). */
  113. #define UBIDI_DEFAULT_LTR 0xfe
  114.  
  115. /** @memo If there is no strong character, then set the paragraph level to 1 (right-to-left). */
  116. #define UBIDI_DEFAULT_RTL 0xff
  117.  
  118. /**
  119.  * @memo Maximum explicit embedding level
  120.  * (The maximum resolved level can be up to <code>UBIDI_MAX_EXPLICIT_LEVEL+1</code>).
  121.  */
  122. #define UBIDI_MAX_EXPLICIT_LEVEL 61
  123.  
  124. /** @memo Bit flag for level input: overrides directional properties. */
  125. #define UBIDI_LEVEL_OVERRIDE 0x80
  126.  
  127. /**
  128.  * @memo <code>UBiDiDirection</code> values indicate the text direction.
  129.  */
  130. enum UBiDiDirection {
  131.     /** @memo All left-to-right text. This is a 0 value. */
  132.     UBIDI_LTR,
  133.     /** @memo All right-to-left text. This is a 1 value. */
  134.     UBIDI_RTL,
  135.     /** @memo Mixed-directional text. */
  136.     UBIDI_MIXED
  137. };
  138.  
  139. typedef enum UBiDiDirection UBiDiDirection;
  140.  
  141. /**
  142.  * Forward declaration of the <code>UBiDi</code> structure for the declaration of
  143.  * the API functions. Its fields are implementation-specific.<p>
  144.  * This structure holds information about a paragraph of text
  145.  * with BiDi-algorithm-related details, or about one line of
  146.  * such a paragraph.<p>
  147.  * Reordering can be done on a line, or on a paragraph which is
  148.  * then interpreted as one single line.
  149.  */
  150. struct UBiDi;
  151.  
  152. typedef struct UBiDi UBiDi;
  153.  
  154. /**
  155.  * Allocate a <code>UBiDi</code> structure.
  156.  * Such an object is initially empty. It is assigned
  157.  * the BiDi properties of a paragraph by <code>ubidi_setPara()</code>
  158.  * or the BiDi properties of a line of a paragraph by
  159.  * <code>ubidi_getLine()</code>.<p>
  160.  * This object can be reused for as long as it is not deallocated
  161.  * by calling <code>ubidi_close()</code>.<p>
  162.  * <code>ubidi_set()</code> will allocate additional memory for
  163.  * internal structures as necessary.
  164.  *
  165.  * @return An empty <code>UBiDi</code> object.
  166.  */
  167. U_CAPI UBiDi * U_EXPORT2
  168. ubidi_open();
  169.  
  170. /**
  171.  * Allocate a <code>UBiDi</code> structure with preallocated memory
  172.  * for internal structures.
  173.  * This function provides a <code>UBiDi</code> object like <code>ubidi_open()</code>
  174.  * with no arguments, but it also preallocates memory for internal structures
  175.  * according to the sizings supplied by the caller.<p>
  176.  * Subsequent functions will not allocate any more memory, and are thus
  177.  * guaranteed not to fail because of lack of memory.<p>
  178.  * The preallocation can be limited to some of the internal memory
  179.  * by setting some values to 0 here. That means that if, e.g.,
  180.  * <code>maxRunCount</code> cannot be reasonably predetermined and should not
  181.  * be set to <code>maxLength</code> (the only failproof value) to avoid
  182.  * wasting memory, then <code>maxRunCount</code> could be set to 0 here
  183.  * and the internal structures that are associated with it will be allocated
  184.  * on demand, just like with <code>ubidi_open()</code>.
  185.  *
  186.  * @param maxLength is the maximum paragraph or line length that internal memory
  187.  *        will be preallocated for. An attempt to associate this object with a
  188.  *        longer text will fail, unless this value is 0, which leaves the allocation
  189.  *        up to the implementation.
  190.  *
  191.  * @param maxRunCount is the maximum anticipated number of same-level runs
  192.  *        that internal memory will be preallocated for. An attempt to access
  193.  *        visual runs on an object that was not preallocated for as many runs
  194.  *        as the text was actually resolved to will fail,
  195.  *        unless this value is 0, which leaves the allocation up to the implementation.<p>
  196.  *        The number of runs depends on the actual text and maybe anywhere between
  197.  *        1 and <code>maxLength</code>. It is typically small.<p>
  198.  *
  199.  * @param pErrorCode must be a valid pointer to an error code value,
  200.  *        which must not indicate a failure before the function call.
  201.  *
  202.  * @return An empty <code>UBiDi</code> object with preallocated memory.
  203.  */
  204. U_CAPI UBiDi * U_EXPORT2
  205. ubidi_openSized(UTextOffset maxLength, UTextOffset maxRunCount, UErrorCode *pErrorCode);
  206.  
  207. /**
  208.  * <code>ubidi_close()</code> must be called to free the memory
  209.  * associated with a UBiDi object.<p>
  210.  *
  211.  * <strong>Important: </strong>
  212.  * If a <code>UBiDi</code> object is the <quote>child</quote>
  213.  * of another one (its <quote>parent</quote>), after calling
  214.  * <code>ubidi_setLine()</code>, then the child object must
  215.  * be destroyed (closed) or reused (by calling
  216.  * <code>ubidi_setPara()</code> or <code>ubidi_setLine()</code>)
  217.  * before the parent object.
  218.  *
  219.  * @param pBiDi is a <code>UBiDi</code> object.
  220.  *
  221.  * @see ubidi_setPara
  222.  * @see ubidi_setLine
  223.  */
  224. U_CAPI void U_EXPORT2
  225. ubidi_close(UBiDi *pBiDi);
  226.  
  227. /**
  228.  * Perform the Unicode BiDi algorithm. It is defined in the
  229.  * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
  230.  * version 5,
  231.  * also described in The Unicode Standard, Version 3.0 .<p>
  232.  *
  233.  * This function takes a single plain text paragraph with or without
  234.  * externally specified embedding levels from <quote>styled</quote> text
  235.  * and computes the left-right-directionality of each character.<p>
  236.  *
  237.  * If the entire paragraph consists of text of only one direction, then
  238.  * the function may not perform all the steps described by the algorithm,
  239.  * i.e., some levels may not be the same as if all steps were performed.
  240.  * This is not relevant for unidirectional text.<br>
  241.  * For example, in pure LTR text with numbers the numbers would get
  242.  * a resolved level of 2 higher than the surrounding text according to
  243.  * the algorithm. This implementation may set all resolved levels to
  244.  * the same value in such a case.<p>
  245.  *
  246.  * The text must be externally split into separate paragraphs (rule P1).
  247.  * Paragraph separators (B) should appear at most at the very end.
  248.  *
  249.  * @param pBiDi A <code>UBiDi</code> object allocated with <code>ubidi_open()</code>
  250.  *        which will be set to contain the reordering information,
  251.  *        especially the resolved levels for all the characters in <code>text</code>.
  252.  *
  253.  * @param text is a pointer to the single-paragraph text that the
  254.  *        BiDi algorithm will be performed on
  255.  *        (step (P1) of the algorithm is performed externally).
  256.  *        <strong>The text must be (at least) <code>length</code> long.</strong>
  257.  *
  258.  * @param length is the length of the text; if <code>length==-1</code> then
  259.  *        the text must be zero-terminated.
  260.  *
  261.  * @param paraLevel specifies the default level for the paragraph;
  262.  *        it is typically 0 (LTR) or 1 (RTL).
  263.  *        If the function shall determine the paragraph level from the text,
  264.  *        then <code>paraLevel</code> can be set to
  265.  *        either <code>UBIDI_DEFAULT_LTR</code>
  266.  *        or <code>UBIDI_DEFAULT_RTL</code>;
  267.  *        if there is no strongly typed character, then
  268.  *        the desired default is used (0 for LTR or 1 for RTL).
  269.  *        Any other value between 0 and <code>UBIDI_MAX_EXPLICIT_LEVEL</code> is also valid,
  270.  *        with odd levels indicating RTL.
  271.  *
  272.  * @param embeddingLevels (in) may be used to preset the embedding and override levels,
  273.  *        ignoring characters like LRE and PDF in the text.
  274.  *        A level overrides the directional property of its corresponding
  275.  *        (same index) character if the level has the
  276.  *        <code>UBIDI_LEVEL_OVERRIDE</code> bit set.<p>
  277.  *        Except for that bit, it must be
  278.  *        <code>paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL</code>.<p>
  279.  *        <strong>Caution: </strong>A copy of this pointer, not of the levels,
  280.  *        will be stored in the <code>UBiDi</code> object;
  281.  *        the <code>embeddingLevels</code> array must not be
  282.  *        deallocated before the <code>UBiDi</code> structure is destroyed or reused,
  283.  *        and the <code>embeddingLevels</code>
  284.  *        should not be modified to avoid unexpected results on subsequent BiDi operations.
  285.  *        However, the <code>ubidi_setPara()</code> and
  286.  *        <code>ubidi_setLine()</code> functions may modify some or all of the levels.<p>
  287.  *        After the <code>UBiDi</code> object is reused or destroyed, the caller
  288.  *        must take care of the deallocation of the <code>embeddingLevels</code> array.<p>
  289.  *        <strong>The <code>embeddingLevels</code> array must be
  290.  *        at least <code>length</code> long.</strong>
  291.  *
  292.  * @param pErrorCode must be a valid pointer to an error code value,
  293.  *        which must not indicate a failure before the function call.
  294.  */
  295. U_CAPI void U_EXPORT2
  296. ubidi_setPara(UBiDi *pBiDi, const UChar *text, UTextOffset length,
  297.               UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
  298.               UErrorCode *pErrorCode);
  299.  
  300. /**
  301.  * <code>ubidi_getLine()</code> sets a <code>UBiDi</code> to
  302.  * contain the reordering information, especially the resolved levels,
  303.  * for all the characters in a line of text. This line of text is
  304.  * specified by referring to a <code>UBiDi</code> object representing
  305.  * this information for a paragraph of text, and by specifying
  306.  * a range of indexes in this paragraph.<p>
  307.  * In the new line object, the indexes will range from 0 to <code>limit-start</code>.<p>
  308.  *
  309.  * This is used after calling <code>ubidi_setPara()</code>
  310.  * for a paragraph, and after line-breaking on that paragraph.
  311.  * It is not necessary if the paragraph is treated as a single line.<p>
  312.  *
  313.  * After line-breaking, rules (L1) and (L2) for the treatment of
  314.  * trailing WS and for reordering are performed on
  315.  * a <code>UBiDi</code> object that represents a line.<p>
  316.  *
  317.  * <strong>Important: </strong><code>pLineBiDi</code> shares data with
  318.  * <code>pParaBiDi</code>.
  319.  * You must destroy or reuse <code>pLineBiDi</code> before <code>pParaBiDi</code>.
  320.  * In other words, you must destroy or reuse the <code>UBiDi</code> object for a line
  321.  * before the object for its parent paragraph.
  322.  *
  323.  * @param pParaBiDi is the parent paragraph object.
  324.  *
  325.  * @param start is the line's first index into the paragraph text.
  326.  *
  327.  * @param limit is just behind the line's last index into the paragraph text
  328.  *        (its last index +1).<br>
  329.  *        It must be <code>0<=start<=limit<=</code>paragraph length.
  330.  *
  331.  * @param pLineBiDi is the object that will now represent a line of the paragraph.
  332.  *
  333.  * @param pErrorCode must be a valid pointer to an error code value,
  334.  *        which must not indicate a failure before the function call.
  335.  *
  336.  * @see ubidi_setPara
  337.  */
  338. U_CAPI void U_EXPORT2
  339. ubidi_setLine(const UBiDi *pParaBiDi,
  340.               UTextOffset start, UTextOffset limit,
  341.               UBiDi *pLineBiDi,
  342.               UErrorCode *pErrorCode);
  343.  
  344. /**
  345.  * Get the directionality of the text.
  346.  *
  347.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  348.  *
  349.  * @return A <code>UBIDI_XXX</code> value that indicates if the entire text
  350.  *         represented by this object is unidirectional,
  351.  *         and which direction, or if it is mixed-directional.
  352.  *
  353.  * @see UBiDiDirection
  354.  */
  355. U_CAPI UBiDiDirection U_EXPORT2
  356. ubidi_getDirection(const UBiDi *pBiDi);
  357.  
  358. /**
  359.  * Get the length of the text.
  360.  *
  361.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  362.  *
  363.  * @return The length of the text that the UBiDi object was created for.
  364.  */
  365. U_CAPI UTextOffset U_EXPORT2
  366. ubidi_getLength(const UBiDi *pBiDi);
  367.  
  368. /**
  369.  * Get the paragraph level of the text.
  370.  *
  371.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  372.  *
  373.  * @return The paragraph level.
  374.  *
  375.  * @see UBiDiLevel
  376.  */
  377. U_CAPI UBiDiLevel U_EXPORT2
  378. ubidi_getParaLevel(const UBiDi *pBiDi);
  379.  
  380. /**
  381.  * Get the level for one character.
  382.  *
  383.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  384.  *
  385.  * @param charIndex the index of a character.
  386.  *
  387.  * @return The level for the character at charIndex.
  388.  *
  389.  * @see UBiDiLevel
  390.  */
  391. U_CAPI UBiDiLevel U_EXPORT2
  392. ubidi_getLevelAt(const UBiDi *pBiDi, UTextOffset charIndex);
  393.  
  394. /**
  395.  * Get an array of levels for each character.<p>
  396.  *
  397.  * Note that this function may allocate memory under some
  398.  * circumstances, unlike <code>ubidi_getLevelAt()</code>.
  399.  *
  400.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  401.  *
  402.  * @param pErrorCode must be a valid pointer to an error code value,
  403.  *        which must not indicate a failure before the function call.
  404.  *
  405.  * @return The levels array for the text,
  406.  *         or <code>NULL</code> if an error occurs.
  407.  *
  408.  * @see UBiDiLevel
  409.  */
  410. U_CAPI const UBiDiLevel * U_EXPORT2
  411. ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode);
  412.  
  413. /**
  414.  * Get a logical run.
  415.  * This function returns information about a run and is used
  416.  * to retrieve runs in logical order.<p>
  417.  * This is especially useful for line-breaking on a paragraph.
  418.  *
  419.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  420.  *
  421.  * @param logicalStart is the first character of the run.
  422.  *
  423.  * @param pLogicalLimit will receive the limit of the run.
  424.  *        The l-value that you point to here may be the
  425.  *        same expression (variable) as the one for
  426.  *        <code>logicalStart</code>.
  427.  *        This pointer can be <code>NULL</code> if this
  428.  *        value is not necessary.
  429.  *
  430.  * @param pLevel will receive the level of the run.
  431.  *        This pointer can be <code>NULL</code> if this
  432.  *        value is not necessary.
  433.  */
  434. U_CAPI void U_EXPORT2
  435. ubidi_getLogicalRun(const UBiDi *pBiDi, UTextOffset logicalStart,
  436.                     UTextOffset *pLogicalLimit, UBiDiLevel *pLevel);
  437.  
  438. /**
  439.  * Get the number of runs.
  440.  * This function may invoke the actual reordering on the
  441.  * <code>UBiDi</code> object, after <code>ubidi_setPara()</code>
  442.  * may have resolved only the levels of the text. Therefore,
  443.  * <code>ubidi_countRuns()</code> may have to allocate memory,
  444.  * and may fail doing so.
  445.  *
  446.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  447.  *
  448.  * @param pErrorCode must be a valid pointer to an error code value,
  449.  *        which must not indicate a failure before the function call.
  450.  *
  451.  * @return The number of runs.
  452.  */
  453. U_CAPI UTextOffset U_EXPORT2
  454. ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
  455.  
  456. /**
  457.  * Get one run's logical start, length, and directionality,
  458.  * which can be 0 for LTR or 1 for RTL.
  459.  * In an RTL run, the character at the logical start is
  460.  * visually on the right of the displayed run.
  461.  * The length is the number of characters in the run.<p>
  462.  * <code>ubidi_countRuns()</code> should be called
  463.  * before the runs are retrieved.
  464.  *
  465.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  466.  *
  467.  * @param runIndex is the number of the run in visual order, in the
  468.  *        range <code>[0..ubidi_countRuns(pBiDi)-1]</code>.
  469.  *
  470.  * @param pLogicalStart is the first logical character index in the text.
  471.  *        The pointer may be <code>NULL</code> if this index is not needed.
  472.  *
  473.  * @param pLength is the number of characters (at least one) in the run.
  474.  *        The pointer may be <code>NULL</code> if this is not needed.
  475.  *
  476.  * @return the directionality of the run,
  477.  *         <code>UBIDI_LTR==0</code> or <code>UBIDI_RTL==1</code>,
  478.  *         never <code>UBIDI_MIXED</code>.
  479.  *
  480.  * @see ubidi_countRuns
  481.  *
  482.  * Example:
  483.  * <pre>
  484.  *  UTextOffset i, count=ubidi_countRuns(pBiDi),
  485.  *          logicalStart, visualIndex=0, length;
  486.  *  for(i=0; i<count; ++i) {
  487.  *      if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &length)) {
  488.  *          do { // LTR
  489.  *              show_char(text[logicalStart++], visualIndex++);
  490.  *          } while(--length>0);
  491.  *      } else {
  492.  *          logicalStart+=length;  // logicalLimit
  493.  *          do { // RTL
  494.  *              show_char(text[--logicalStart], visualIndex++);
  495.  *          } while(--length>0);
  496.  *      }
  497.  *  }
  498.  * </pre>
  499.  *
  500.  * Note that in right-to-left runs, code like this places
  501.  * modifier letters before base characters and second surrogates
  502.  * before first ones.
  503.  */
  504. U_CAPI UBiDiDirection U_EXPORT2
  505. ubidi_getVisualRun(UBiDi *pBiDi, UTextOffset runIndex,
  506.                    UTextOffset *pLogicalStart, UTextOffset *pLength);
  507.  
  508. /**
  509.  * Get the visual position from a logical text position.
  510.  * If such a mapping is used many times on the same
  511.  * <code>UBiDi</code> object, then calling
  512.  * <code>ubidi_getLogicalMap()</code> is more efficient.<p>
  513.  *
  514.  * Note that in right-to-left runs, this mapping places
  515.  * modifier letters before base characters and second surrogates
  516.  * before first ones.
  517.  *
  518.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  519.  *
  520.  * @param logicalIndex is the index of a character in the text.
  521.  *
  522.  * @param pErrorCode must be a valid pointer to an error code value,
  523.  *        which must not indicate a failure before the function call.
  524.  *
  525.  * @return The visual position of this character.
  526.  *
  527.  * @see ubidi_getLogicalMap
  528.  * @see ubidi_getLogicalIndex
  529.  */
  530. U_CAPI UTextOffset U_EXPORT2
  531. ubidi_getVisualIndex(UBiDi *pBiDi, UTextOffset logicalIndex, UErrorCode *pErrorCode);
  532.  
  533. /**
  534.  * Get the logical text position from a visual position.
  535.  * If such a mapping is used many times on the same
  536.  * <code>UBiDi</code> object, then calling
  537.  * <code>ubidi_getVisualMap()</code> is more efficient.<p>
  538.  *
  539.  * This is the inverse function to <code>ubidi_getVisualIndex()</code>.
  540.  *
  541.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  542.  *
  543.  * @param visualIndex is the visual position of a character.
  544.  *
  545.  * @param pErrorCode must be a valid pointer to an error code value,
  546.  *        which must not indicate a failure before the function call.
  547.  *
  548.  * @return The index of this character in the text.
  549.  *
  550.  * @see ubidi_getVisualMap
  551.  * @see ubidi_getVisualIndex
  552.  */
  553. U_CAPI UTextOffset U_EXPORT2
  554. ubidi_getLogicalIndex(UBiDi *pBiDi, UTextOffset visualIndex, UErrorCode *pErrorCode);
  555.  
  556. /**
  557.  * Get a logical-to-visual index map (array) for the characters in the UBiDi
  558.  * (paragraph or line) object.
  559.  *
  560.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  561.  *
  562.  * @param indexMap is a pointer to an array of <code>ubidi_getLength()</code>
  563.  *        indexes which will reflect the reordering of the characters.
  564.  *        The array does not need to be initialized.<p>
  565.  *        The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.<p>
  566.  *
  567.  * @param pErrorCode must be a valid pointer to an error code value,
  568.  *        which must not indicate a failure before the function call.
  569.  *
  570.  * @see ubidi_getVisualMap
  571.  * @see ubidi_getVisualIndex
  572.  */
  573. U_CAPI void U_EXPORT2
  574. ubidi_getLogicalMap(UBiDi *pBiDi, UTextOffset *indexMap, UErrorCode *pErrorCode);
  575.  
  576. /**
  577.  * Get a visual-to-logical index map (array) for the characters in the UBiDi
  578.  * (paragraph or line) object.
  579.  *
  580.  * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
  581.  *
  582.  * @param indexMap is a pointer to an array of <code>ubidi_getLength()</code>
  583.  *        indexes which will reflect the reordering of the characters.
  584.  *        The array does not need to be initialized.<p>
  585.  *        The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.<p>
  586.  *
  587.  * @param pErrorCode must be a valid pointer to an error code value,
  588.  *        which must not indicate a failure before the function call.
  589.  *
  590.  * @see ubidi_getLogicalMap
  591.  * @see ubidi_getLogicalIndex
  592.  */
  593. U_CAPI void U_EXPORT2
  594. ubidi_getVisualMap(UBiDi *pBiDi, UTextOffset *indexMap, UErrorCode *pErrorCode);
  595.  
  596. /**
  597.  * This is a convenience function that does not use a UBiDi object.
  598.  * It is intended to be used for when an application has determined the levels
  599.  * of objects (character sequences) and just needs to have them reordered (L2).
  600.  * This is equivalent to using <code>ubidi_getLogicalMap</code> on a
  601.  * <code>UBiDi</code> object.
  602.  *
  603.  * @param levels is an array with <code>length</code> levels that have been determined by
  604.  *        the application.
  605.  *
  606.  * @param length is the number of levels in the array, or, semantically,
  607.  *        the number of objects to be reordered.
  608.  *        It must be <code>length>0</code>.
  609.  *
  610.  * @param indexMap is a pointer to an array of <code>length</code>
  611.  *        indexes which will reflect the reordering of the characters.
  612.  *        The array does not need to be initialized.<p>
  613.  *        The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.
  614.  */
  615. U_CAPI void U_EXPORT2
  616. ubidi_reorderLogical(const UBiDiLevel *levels, UTextOffset length, UTextOffset *indexMap);
  617.  
  618. /**
  619.  * This is a convenience function that does not use a UBiDi object.
  620.  * It is intended to be used for when an application has determined the levels
  621.  * of objects (character sequences) and just needs to have them reordered (L2).
  622.  * This is equivalent to using <code>ubidi_getVisualMap</code> on a
  623.  * <code>UBiDi</code> object.
  624.  *
  625.  * @param levels is an array with <code>length</code> levels that have been determined by
  626.  *        the application.
  627.  *
  628.  * @param length is the number of levels in the array, or, semantically,
  629.  *        the number of objects to be reordered.
  630.  *        It must be <code>length>0</code>.
  631.  *
  632.  * @param indexMap is a pointer to an array of <code>length</code>
  633.  *        indexes which will reflect the reordering of the characters.
  634.  *        The array does not need to be initialized.<p>
  635.  *        The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.
  636.  */
  637. U_CAPI void U_EXPORT2
  638. ubidi_reorderVisual(const UBiDiLevel *levels, UTextOffset length, UTextOffset *indexMap);
  639.  
  640. /**
  641.  * Invert an index map.
  642.  * The one-to-one index mapping of the first map is inverted and written to
  643.  * the second one.
  644.  *
  645.  * @param srcMap is an array with <code>length</code> indexes
  646.  *        which define the original mapping.
  647.  *
  648.  * @param destMap is an array with <code>length</code> indexes
  649.  *        which will be filled with the inverse mapping.
  650.  *
  651.  * @param length is the length of each array.
  652.  */
  653. U_CAPI void U_EXPORT2
  654. ubidi_invertMap(const UTextOffset *srcMap, UTextOffset *destMap, UTextOffset length);
  655.  
  656. /**
  657.  * @name Sample code for the ICU BiDi API
  658.  *
  659.  * <h2>Rendering a paragraph with the ICU BiDi API</h2>
  660.  *
  661.  * This is (hypothetical) sample code that illustrates
  662.  * how the ICU BiDi API could be used to render a paragraph of text.
  663.  * Rendering code depends highly on the graphics system,
  664.  * therefore this sample code must make a lot of assumptions,
  665.  * which may or may not match any existing graphics system's properties.
  666.  *
  667.  * <p>The basic assumptions are:</p>
  668.  * <ul>
  669.  * <li>Rendering is done from left to right on a horizontal line.</li>
  670.  * <li>A run of single-style, unidirectional text can be rendered at once.</li>
  671.  * <li>Such a run of text is passed to the graphics system with
  672.  *     characters (code units) in logical order.</li>
  673.  * <li>The line-breaking algorithm is very complicated
  674.  *     and Locale-dependent -
  675.  *     and therefore its implementation omitted from this sample code.</li>
  676.  * </ul>
  677.  *
  678.  * <pre>
  679.  *  #include "ubidi.h"
  680.  *  
  681.  *  typedef enum {
  682.  *      styleNormal=0, styleSelected=1,
  683.  *      styleBold=2, styleItalics=4,
  684.  *      styleSuper=8, styleSub=16
  685.  *  } Style;
  686.  *  
  687.  *  typedef struct { UTextOffset limit; Style style; } StyleRun;
  688.  *  
  689.  *  int getTextWidth(const UChar *text, UTextOffset start, UTextOffset limit,
  690.  *                   const StyleRun *styleRuns, int styleRunCount);
  691.  *  
  692.  *  // set *pLimit and *pStyleRunLimit for a line
  693.  *  // from text[start] and from styleRuns[styleRunStart]
  694.  *  // using ubidi_getLogicalRun(para, ...)
  695.  *  void getLineBreak(const UChar *text, UTextOffset start, UTextOffset *pLimit,
  696.  *                    UBiDi *para,
  697.  *                    const StyleRun *styleRuns, int styleRunStart, int *pStyleRunLimit,
  698.  *                    int *pLineWidth);
  699.  *  
  700.  *  // render runs on a line sequentially, always from left to right
  701.  *  
  702.  *  // prepare rendering a new line
  703.  *  void startLine(UBiDiDirection textDirection, int lineWidth);
  704.  *  
  705.  *  // render a run of text and advance to the right by the run width
  706.  *  // the text[start..limit-1] is always in logical order
  707.  *  void renderRun(const UChar *text, UTextOffset start, UTextOffset limit,
  708.  *                 UBiDiDirection textDirection, Style style);
  709.  *  
  710.  *  // We could compute a cross-product
  711.  *  // from the style runs with the directional runs
  712.  *  // and then reorder it.
  713.  *  // Instead, here we iterate over each run type
  714.  *  // and render the intersections -
  715.  *  // with shortcuts in simple (and common) cases.
  716.  *  // renderParagraph() is the main function.
  717.  *  
  718.  *  // render a directional run with
  719.  *  // (possibly) multiple style runs intersecting with it
  720.  *  void renderDirectionalRun(const UChar *text,
  721.  *                            UTextOffset start, UTextOffset limit,
  722.  *                            UBiDiDirection direction,
  723.  *                            const StyleRun *styleRuns, int styleRunCount) {
  724.  *      int i;
  725.  *  
  726.  *      // iterate over style runs
  727.  *      if(direction==UBIDI_LTR) {
  728.  *          int styleLimit;
  729.  *  
  730.  *          for(i=0; i<styleRunCount; ++i) {
  731.  *              styleLimit=styleRun[i].limit;
  732.  *              if(start<styleLimit) {
  733.  *                  if(styleLimit>limit) { styleLimit=limit; }
  734.  *                  renderRun(text, start, styleLimit,
  735.  *                            direction, styleRun[i].style);
  736.  *                  if(styleLimit==limit) { break; }
  737.  *                  start=styleLimit;
  738.  *              }
  739.  *          }
  740.  *      } else {
  741.  *          int styleStart;
  742.  *  
  743.  *          for(i=styleRunCount-1; i>=0; --i) {
  744.  *              if(i>0) {
  745.  *                  styleStart=styleRun[i-1].limit;
  746.  *              } else {
  747.  *                  styleStart=0;
  748.  *              }
  749.  *              if(limit>=styleStart) {
  750.  *                  if(styleStart<start) { styleStart=start; }
  751.  *                  renderRun(text, styleStart, limit,
  752.  *                            direction, styleRun[i].style);
  753.  *                  if(styleStart==start) { break; }
  754.  *                  limit=styleStart;
  755.  *              }
  756.  *          }
  757.  *      }
  758.  *  }
  759.  *  
  760.  *  // the line object represents text[start..limit-1]
  761.  *  void renderLine(UBiDi *line, const UChar *text,
  762.  *                  UTextOffset start, UTextOffset limit,
  763.  *                  const StyleRun *styleRuns, int styleRunCount) {
  764.  *      UBiDiDirection direction=ubidi_getDirection(line);
  765.  *      if(direction!=UBIDI_MIXED) {
  766.  *          // unidirectional
  767.  *          if(styleRunCount<=1) {
  768.  *              renderRun(text, start, limit, direction, styleRuns[0].style);
  769.  *          } else {
  770.  *              renderDirectionalRun(text, start, limit, 
  771.  *                                   direction, styleRuns, styleRunCount);
  772.  *          }
  773.  *      } else {
  774.  *          // mixed-directional
  775.  *          UTextOffset count, i, length;
  776.  *          UBiDiLevel level;
  777.  *  
  778.  *          count=ubidi_countRuns(para, pErrorCode);
  779.  *          if(U_SUCCESS(*pErrorCode)) {
  780.  *              if(styleRunCount<=1) {
  781.  *                  Style style=styleRuns[0].style;
  782.  *  
  783.  *                  // iterate over directional runs
  784.  *                  for(i=0; i<count; ++i) {
  785.  *                      direction=ubidi_getVisualRun(para, i, &start, &length);
  786.  *                      renderRun(text, start, start+length, direction, style);
  787.  *                  }
  788.  *              } else {
  789.  *                  UTextOffset j;
  790.  *  
  791.  *                  // iterate over both directional and style runs
  792.  *                  for(i=0; i<count; ++i) {
  793.  *                      direction=ubidi_getVisualRun(line, i, &start, &length);
  794.  *                      renderDirectionalRun(text, start, start+length, 
  795.  *                                           direction, styleRuns, styleRunCount);
  796.  *                  }
  797.  *              }
  798.  *          }
  799.  *      }
  800.  *  }
  801.  *  
  802.  *  void renderParagraph(const UChar *text, UTextOffset length,
  803.  *                       UBiDiDirection textDirection,
  804.  *                       const StyleRun *styleRuns, int styleRunCount,
  805.  *                       int lineWidth,
  806.  *                       UErrorCode *pErrorCode) {
  807.  *      UBiDi *para;
  808.  *  
  809.  *      if(pErrorCode==NULL || U_FAILURE(*pErrorCode) || length<=0) {
  810.  *          return;
  811.  *      }
  812.  *  
  813.  *      para=ubidi_openSized(length, 0, pErrorCode);
  814.  *      if(para==NULL) { return; }
  815.  *  
  816.  *      ubidi_setPara(para, text, length,
  817.  *                    textDirection ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,
  818.  *                    NULL, pErrorCode);
  819.  *      if(U_SUCCESS(*pErrorCode)) {
  820.  *          UBiDiLevel paraLevel=1&ubidi_getParaLevel(para);
  821.  *          StyleRun styleRun={ length, styleNormal };
  822.  *          int width;
  823.  *  
  824.  *          if(styleRuns==NULL || styleRunCount<=0) {
  825.  *              styleRunCount=1;
  826.  *              styleRuns=&styleRun;
  827.  *          }
  828.  *  
  829.  *          // assume styleRuns[styleRunCount-1].limit>=length
  830.  *  
  831.  *          width=getTextWidth(text, 0, length, styleRuns, styleRunCount);
  832.  *          if(width<=lineWidth) {
  833.  *              // everything fits onto one line
  834.  *  
  835.  *              // prepare rendering a new line from either left or right
  836.  *              startLine(paraLevel, width);
  837.  *  
  838.  *              renderLine(para, text, 0, length,
  839.  *                         styleRuns, styleRunCount);
  840.  *          } else {
  841.  *              UBiDi *line;
  842.  *  
  843.  *              // we need to render several lines
  844.  *              line=ubidi_openSized(length, 0, pErrorCode);
  845.  *              if(line!=NULL) {
  846.  *                  UTextOffset start=0, limit;
  847.  *                  int styleRunStart=0, styleRunLimit;
  848.  *  
  849.  *                  for(;;) {
  850.  *                      limit=length;
  851.  *                      styleRunLimit=styleRunCount;
  852.  *                      getLineBreak(text, start, &limit, para,
  853.  *                                   styleRuns, styleRunStart, &styleRunLimit,
  854.  *                                   &width);
  855.  *                      ubidi_setLine(para, start, limit, line, pErrorCode);
  856.  *                      if(U_SUCCESS(*pErrorCode)) {
  857.  *                          // prepare rendering a new line
  858.  *                          // from either left or right
  859.  *                          startLine(paraLevel, width);
  860.  *  
  861.  *                          renderLine(line, text, start, limit,
  862.  *                                     styleRuns+styleRunStart,
  863.  *                                     styleRunLimit-styleRunStart);
  864.  *                      }
  865.  *                      if(limit==length) { break; }
  866.  *                      start=limit;
  867.  *                      styleRunStart=styleRunLimit-1;
  868.  *                      if(start>=styleRuns[styleRunStart].limit) {
  869.  *                          ++styleRunStart;
  870.  *                      }
  871.  *                  }
  872.  *  
  873.  *                  ubidi_close(line);
  874.  *              }
  875.  *          }
  876.  *      }
  877.  *  
  878.  *      ubidi_close(para);
  879.  *  }
  880.  * </pre>
  881.  */
  882. BIDI_SAMPLE_CODE
  883. /*@{*/
  884. /*@}*/
  885.  
  886. /*@}*/
  887.  
  888. #endif
  889.